package container

import (
	"bzppx-codepub-server/bzppx-agent/app/utils"
	"bzppx-codepub-server/bzppx-agent/message"
	"github.com/gogf/gf/g/os/glog"
	"time"
)

// NewWorker: worker实例生成
func NewWorker() *Worker {
	return &Worker{}
}

type Worker struct{}

// StartTask: 启动一个任务
func (w *Worker) StartTask() {
	for {
		tasks := Ctx.Tasks.GetDefaultTasks()
		if len(tasks) == 0 {
			time.Sleep(2 * time.Second)
			continue
		}

		for _, task := range tasks {
			glog.Debugf("获取到task任务:%#v", task)
			pathIsHave := Ctx.Tasks.PathIsHaveTask(task.Path)
			glog.Debugf("检查此路径下是否有正在执行的任务:%v", pathIsHave)
			if pathIsHave {
				continue
			}
			// 启动新任务 (从任务列表里消费一个任务)
			err := Ctx.Tasks.Start(task.TaskLogId)
			if err != nil {
				glog.Error(err.Error())
				continue
			}
			glog.Debugf("启动新任务")
			go func(task *message.TaskMessage) {
				defer func() {
					e := recover()
					if e != nil {
						glog.Errorf("任务执行异常 task handle crash, %v", e)
						// 异常结束任务
						Ctx.Tasks.End(task.TaskLogId, message.Task_Failed, "task runtime crash", "")
					}
				}()

				glog.Info("agent task " + task.TaskLogId + " publish start")

				// start exec pre_command (执行前置任务)
				if task.PreCommandX.Command != "" {
					err := utils.NewCommandX().Exec(task.PreCommandX)
					if err != nil {
						glog.Debugf("运行前置任务失败:%#v", task.PreCommandX.Command)
						glog.Error("agent task " + task.TaskLogId + " exec pre_command faild: " + err.Error())
						if task.PreCommandX.CommandExecType == utils.Command_ExecType_SyncErrorStop {
							// 异常结束任务
							Ctx.Tasks.End(task.TaskLogId, message.Task_Failed, "exec pre_command error: "+err.Error(), "")
							return
						}
					} else {
						glog.Debugf("运行前置任务成功:%#v", task.PreCommandX.Command)
						glog.Info("agent task " + task.TaskLogId + " exec pre_command success")
					}
				}

				// start publish code (拉取代码)
				commitId, err := utils.NewGitX().Publish(task.GitX)
				if err != nil {
					glog.Error("agent task " + task.TaskLogId + " publish faild: " + err.Error())
					Ctx.Tasks.End(task.TaskLogId, message.Task_Failed, "publish code error: "+err.Error(), commitId)
					return
				}

				glog.Debug("拉取代码成功")
				glog.Info("agent task " + task.TaskLogId + " publish code success, commit_id: " + commitId)

				// start exec post_command (执行后置命令)
				if task.PostCommandX.Command != "" {
					err = utils.NewCommandX().Exec(task.PostCommandX)
					if err != nil {
						glog.Errorf("运行后置命令失败:%s", task.PostCommandX.Command)
						glog.Error("agent task " + task.TaskLogId + " exec post_command faild: " + err.Error())
						if task.PostCommandX.CommandExecType == utils.Command_ExecType_SyncErrorStop {
							Ctx.Tasks.End(task.TaskLogId, message.Task_Failed, "exec post_command error: "+err.Error(), "")
							return
						}
					} else {
						glog.Debugf("运行后置命令成功:%s", task.PostCommandX.Command)

						glog.Info("agent task " + task.TaskLogId + " exec post_command success")
					}
				}

				Ctx.Tasks.End(task.TaskLogId, message.Task_Success, "success", commitId)
				glog.Debug("任务执行完成")
				glog.Info("agent task " + task.TaskLogId + " publish end")
			}(task)
		}
		time.Sleep(2 * time.Second)
	}
}
